package com.boc.ewr.risk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.boc.ewr.bcimp.entity.BusAcctInfo;
import com.boc.ewr.bcimp.entity.Cac;
import com.boc.ewr.bcimp.entity.Pro;
import com.boc.ewr.bcimp.mapper.BusAcctInfoMapper;
import com.boc.ewr.bcimp.mapper.CacMapper;
import com.boc.ewr.bcimp.service.IBusAcctInfoService;
import com.boc.ewr.risk.entity.HeadlessCac;
import com.boc.ewr.risk.entity.vo.CacSameMobCusmNoVo;
import com.boc.ewr.risk.entity.vo.SamePersonMuchAcctVo;
import com.boc.ewr.risk.service.ICacRiskService;
import com.boc.ewr.risk.service.IHeadlessCacService;
import net.bytebuddy.asm.Advice;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.C;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.dto.message.TemplateDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author : Wzz
 * @create : 2023-05- 05- 16:55
 * @desc :
 */
@Service
public class CacRiskServiceImpl extends ServiceImpl<CacMapper, Cac> implements ICacRiskService {

    @Autowired
    private IHeadlessCacService headlessCacService;

    @Autowired
    private CacMapper cacMapper;

    @Autowired
    private BusAcctInfoMapper busAcctInfoMapper;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Autowired
    private IBusAcctInfoService busAcctInfoService;

    Pattern pattern = Pattern.compile("^.*?(基本账户|临时账户|专用账户|一般账户).*");


    /**
     * 同手机号存在不同客户号:
     * CAC中相同电话、手机号出现在不同客户号下，如有相符的，提示识别客户是否开设虚假账户。
     * 提示关注该类客户风险情况
     */
    @Override
    public List<Cac> judgeSamePhoneNum() {
        List<Cac> cacList = cacMapper.judgeSamePhoneNum();

        return cacList;
    }

    /**
     * 同法人、财务负责人拥有3个及以上的客户号:
     * CAC中如有同法人、财务负责人拥有3个及以上的客户号的，提示高风险法人、财务负责人。
     * 推送至二级行或网点，提示高风险法人、财务负责人
     */
    @Override
    public List<SamePersonMuchAcctVo> judgeSamePersonMuchAcct() {
        List<SamePersonMuchAcctVo> resultList = new ArrayList<>();

        List<SamePersonMuchAcctVo> busAcctInfoSamePersonMuchAcctVoList
                = busAcctInfoMapper.judgeSamePersonMuchAcct();
        busAcctInfoSamePersonMuchAcctVoList.forEach(e -> e.setNote("法人相同"));

/*
        List<SamePersonMuchAcctVo> cacSamePersonMuchAcctVoList
                = cacMapper.judgeSamePersonMuchAcct();
        cacSamePersonMuchAcctVoList.forEach(e -> e.setNote("财务负责人相同"));
*/

        resultList.addAll(busAcctInfoSamePersonMuchAcctVoList);
//        resultList.addAll(cacSamePersonMuchAcctVoList);

        return resultList;
    }


    /**
     * 无头账户监控：
     * CAC中如有 无结算户 的 同客户号的，提示无企业结算账户
     * 推送至二级行或网点，提示无企业结算账户可维护为特殊不对账账户
     * <p>
     * 基本账户、临时账户、专用账户、一般账户为结算账户，其余为非结算账户
     *
     * ######该功能查询数据量较大，改为定时任务触发，保存到表中储存######
     */
    @Override
    public void noneBusAcct() {
        // 清除之前数据
        headlessCacService.remove(null);

        // 获取全部Cac
        List<Cac> cacList = this.list(
                new LambdaQueryWrapper<Cac>()
                        .orderByAsc(Cac::getCusmNo)
        );
        Set<String> accNoSet = cacList.stream()
                .map(Cac::getAccNo)
                .collect(Collectors.toSet());

        // 获取同客户号下的全部账户号
        Map<String, List<String>> cusmAcctMap = new HashMap<>();
        for (Cac cac : cacList) {
            String cusmNo = cac.getCusmNo();
            String acctNo = cac.getAccNo();
            if (cusmAcctMap.containsKey(cusmNo)) {
                cusmAcctMap.get(cusmNo).add(acctNo);
            } else {
                List<String> acctList = new ArrayList<>();
                acctList.add(acctNo);
                cusmAcctMap.put(cusmNo, acctList);
            }
        }

        // 获取全部结算账户对应的账号
        Set<String> settlementAcctSet = busAcctInfoMapper.selectList(
                new LambdaQueryWrapper<BusAcctInfo>()
                        .isNotNull(BusAcctInfo::getActType)
                        .like(BusAcctInfo::getActType, "基本账户").or()
                        .like(BusAcctInfo::getActType, "临时账户").or()
                        .like(BusAcctInfo::getActType, "专用账户").or()
                        .like(BusAcctInfo::getActType, "一般账户")
        ).stream().map(BusAcctInfo::getAccNo).collect(Collectors.toSet());

        // 客户号Set集合
        Set<String> cusmNoSet = cusmAcctMap.keySet();
        // 结果对应的客户号Set集合
        Set<String> resultSet = new HashSet<>();
        for (String cusmNo : cusmNoSet) {
            List<String> accNoList = cusmAcctMap.get(cusmNo);
            // 账户List中任意一个值存在于 结算账户对应的账号中，则不属于无头账户
            if(accNoList.stream().noneMatch(settlementAcctSet::contains)){
                resultSet.add(cusmNo);
            }
        }

        List<Cac> cacResultList = cacMapper.selectList(
                new LambdaQueryWrapper<Cac>()
                        .in(Cac::getCusmNo, resultSet)
        );

        List<HeadlessCac> resultList = new ArrayList<>();
        for (Cac cac : cacResultList) {
            HeadlessCac headlessCac = new HeadlessCac();
            BeanUtils.copyProperties(cac,headlessCac);
            resultList.add(headlessCac);
        }

        headlessCacService.saveBatch(resultList);
    }

    private String getUserAcctName() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        return sysUser.getUsername();
    }
}
